
package com.x52im.rbchat.logic.contact;

import android.content.Intent;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.eva.android.widget.DataLoadableFragment;
import com.eva.android.widget.LetterIndexBar;
import com.x52im.rbchat.MyApplication;
import com.x52im.rbchat.logic.chat_friend.gift.GiftsToolsPopupWindow;
import com.x52im.rbchat.logic.chat_friend.utils.ObserverFactory;
import com.x52im.rbchat.logic.contact.model.FooterItemValue;
import com.x52im.rbchat.logic.contact.model.FriendRequestHeaderItemValue;
import com.x52im.rbchat.logic.contact.model.FriendItemValue;
import com.x52im.rbchat.logic.contact.model.HeaderItemValue;
import com.x52im.rbchat.logic.contact.viewholder.head.AddFriendItemViewHolder;
import com.x52im.rbchat.logic.contact.viewholder.foot.FriendCountItemViewHolder;
import com.x52im.rbchat.logic.contact.viewholder.foot.FooterItemViewHolder;
import com.x52im.rbchat.logic.contact.viewholder.head.FriendRequestItemViewHolder;
import com.x52im.rbchat.logic.contact.viewholder.head.GroupItemViewHolder;
import com.x52im.rbchat.logic.contact.viewholder.head.HeaderItemViewHolder;
import com.x52im.rbchat.logic.contact.viewmodel.FriendsReqViewModel;
import com.x52im.rbchat.logic.contact.viewmodel.FriendsViewModel;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.x52im.rbchat.R;
import com.x52im.rbchat.network.http.async.QueryFriendInfo;
import com.x52im.rbchat.utils.ActivityRequestCode;
import com.x52im.rbchat.utils.IntentFactory;

import java.util.List;
import java.util.Observer;

/**
 * 基于Fragment的新版好友列表界面实现类。
 *
 * @author JackJiang
 * @since 8.0
 */
public class FriendListFragment extends DataLoadableFragment implements LetterIndexBar.OnLetterIndexSlectionListener, FriendListAdapter.OnItemClickListener {

    private final static String TAG = FriendListFragment.class.getSimpleName();

    private FriendsViewModel viewModel4Friends;
    private FriendsReqViewModel viewModel4FriendsReq;

    private LinearLayoutManager layoutManager;
    private RecyclerView recyclerView4Friends;
    private FriendListAdapter listAdapter4Friends;

    /** 是否显示按字母快速索引组件 */
    private boolean showLetterIndexBar;
    /** 按字母快速索引组件 */
    private LetterIndexBar viewLetterIndexBar;
    /** 当前选中的快速索引字母显示组件 */
    private TextView viewLetter4CurrentIndex;

    //-------------------------------------------------------------------------- 礼品相关 S
    /** 礼品工具包装类 */
    private GiftsToolsPopupWindow giftsToolsPopupWindow = null;
    /**
     * 收到好友发过来的礼品观察者对象.
     * 目前此观察者只要用于聊天界面中在收到礼品后能即时刷新“我的礼品包”的ui展现之用. */
    private Observer receivedGiftObserverForCommonUI = null;//new ObserverProvider.ReceivedGiftObserverForCommonUI(this);
    //-------------------------------------------------------------------------- 礼品相关 E

    // [注意1]：Fragment中的onResume方法，在很多时候并不像Activity那样能被即时调用（比如当多个Fragment放置于
    //         ViewPager中时，子fragment的左右切换是不会触发Fragment的onResume方法，此时就需要与 setUserVisibleHint
    //         方法进行配合才能保证兜底（理论上，Fragment中的setUserVisibleHint和onResume方法，在Fragment
    //         可见性改变时总有一个会被调用），这样就能确保像Activity中那样不错过任何一次可性的触发
    // [注意2]：setUserVisibleHint方法中切不可调用涉及ui的代码，所有有关ui的代码都都应放在onCreateView内或之后调用，
    //         否则可能因Fragment在Activity中的生命周期问题，导致fragment中getActivity()或getContext()为null，
    //         但很适合在这样的方法中借助ViewModel+LiveData进行数据的加载和刷新（因其能自动处理Fragment和Activity
    //         的生命周期问题，因而这样用非常安全可靠）
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (listAdapter4Friends != null && isVisibleToUser) {
            Log.i(TAG, "@@@@ AA-setUserVisibleHint已被调用，马上开始 reloadFriendsData()、reloadUnreadCountData()... "+System.currentTimeMillis());
            viewModel4Friends.reloadFriendsData();
            viewModel4FriendsReq.reloadUnreadCountData();
        }
    }

    @Override
    public void onCreateAfter() {
        // 拿到本类对应的ViewModel对象，实现MVVM架构
        viewModel4Friends = ViewModelProviders.of(getActivity()).get(FriendsViewModel.class);
        viewModel4FriendsReq = ViewModelProviders.of(getActivity()).get(FriendsReqViewModel.class);
    }

    // 注意：Fragment中的onResume方法，在很多时候并不像Activity那样能被即时调用（比如当多个Fragment放置于
    // ViewPager中时，子fragment的左右切换是不会触发Fragment的onResume方法，此时就需要与 setUserVisibleHint
    // 方法进行配合才能保证兜底（理论上，Fragment中的setUserVisibleHint和onResume方法，在Fragment可见性改变时
    // 总有一个会被调用），这样就能确保像Activity中那样不错过任何一次可性的触发
    @Override
    public void onResume() {
        super.onResume();
        Log.i(TAG, "@@@@ AA-onResume已被调用，马上开始 reloadFriendsData()、reloadUnreadCountData()... "+System.currentTimeMillis());
        viewModel4Friends.reloadFriendsData();
        viewModel4FriendsReq.reloadUnreadCountData();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();

        //******************************************************************************** 礼品相关代码 START
        MyApplication.getInstance2().getIMClientManager().getTransDataListener().setReceivedGiftObserverForCommonUI(null);
        if(giftsToolsPopupWindow != null)
            giftsToolsPopupWindow.forParentPause();
        //******************************************************************************** 礼品相关代码 END
    }

    /**
     * 处理回调.
     * {@inheritDoc}
     */
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //-------------------------------------------------------------------------- 礼品相关 S
        if (requestCode == ActivityRequestCode.GIFTS_RECHARGE_CIONS_RESULT) {
            if (giftsToolsPopupWindow != null)
                giftsToolsPopupWindow.forParentAvtivityResult();
        }
        //-------------------------------------------------------------------------- 礼品相关 E
    }

    @Override
    protected int contentLayout() {
        return R.layout.contact_list_fragment;
    }

    @Override
    protected View initViews(@NonNull LayoutInflater inflater, @Nullable ViewGroup container){
        View view = super.initViews(inflater, container);

        this.initSubViews();
        this.initDatas();

        return view;
    }

    /**
     * 初始各种内容ui组件等。
     */
    private void initSubViews() {

        this.recyclerView4Friends = contentView.findViewById(R.id.usersRecyclerView);
        this.viewLetterIndexBar =  contentView.findViewById(R.id.quickIndexBar);
        this.viewLetter4CurrentIndex = contentView.findViewById(R.id.indexLetterTextView);

        listAdapter4Friends = onCreateUserListAdapter();
        listAdapter4Friends.setOnItemClickListener(this);

        initHeaderViewHolders();
        initFooterViewHolders();

        recyclerView4Friends.setAdapter(listAdapter4Friends);
        layoutManager = new LinearLayoutManager(getActivity());
        recyclerView4Friends.setLayoutManager(layoutManager);

        if (showLetterIndexBar) {
            viewLetterIndexBar.setVisibility(View.VISIBLE);
            viewLetterIndexBar.setOnLetterIndexSelectionListener(this);
        } else {
            viewLetterIndexBar.setVisibility(View.GONE);
        }

        //******************************************************************************** 礼品相关代码 START
        receivedGiftObserverForCommonUI = new ObserverFactory.ReceivedGiftObserverForCommonUI(getActivity());
        MyApplication.getInstance2().getIMClientManager().getTransDataListener().setReceivedGiftObserverForCommonUI(receivedGiftObserverForCommonUI);
        if(giftsToolsPopupWindow != null)
            giftsToolsPopupWindow.forParentResume();
        //******************************************************************************** 礼品相关代码 END
    }

    private void initDatas(){
        // 通过LiveData的观察者机制，实现好友数据加载完成的通知，以便即时在ui显示出来
        this.viewModel4Friends.getFriendsDataReloadLiveData().observe(this, userInfos -> {
            // 显示内容ui
            showContent();
            // 为列表设置数据并显示最新数据
            listAdapter4Friends.setUsers(userInfos);

            Log.i(TAG, "@@@@【FriendListFragment】收到reload完成的postValue！");
        });

        // 通过LiveData的观察者机制，实现好友数据发生变动时接收通知，以便即时在ui显示出来
        this.viewModel4Friends.getFriendsDataChangedLiveData().observe(this, friendUid -> {
            // 刷新列表ui（之所以不是刷新指定的index行，原因是LiveData中的postValue方法会去掉重复通知，在极端
            // 情况下就有可能丢失数据变动能知，导致有些item就得不到更新，直接全列表刷新就能确保万无一失啦）
//            listAdapter4Friends.notifyDataSetChanged();
            notifyVisibleDataSetChanged(layoutManager, listAdapter4Friends);

            Log.i(TAG, "@@@@【FriendListFragment】收到dataChanged完成的postValue！");
        });

        // 通过LiveData的观察者机制，实现加好友请求未读数发生变动时接收通知，以便即时在ui显示出来
        this.viewModel4FriendsReq.getUnreadCountChangedLiveData().observe(this, unreadreqCount -> {
            listAdapter4Friends.updateHeader(0, new FriendRequestHeaderItemValue(unreadreqCount));
            // 刷新ui显示
            listAdapter4Friends.notifyItemChanged(0);
            Log.i(TAG, "@@@@【FriendListFragment】收到unreadreqCount变动的postValue！");
        });
    }

    protected FriendListAdapter onCreateUserListAdapter() {
        return new FriendListAdapter(this);
    }

    public void initHeaderViewHolders() {
        addHeaderViewHolder(FriendRequestItemViewHolder.class, R.layout.contact_item_header_friendreq, new FriendRequestHeaderItemValue(viewModel4FriendsReq.getUnreadCount()));
        addHeaderViewHolder(AddFriendItemViewHolder.class, R.layout.contact_item_header_addfriend, new HeaderItemValue());
        addHeaderViewHolder(GroupItemViewHolder.class, R.layout.contact_item_header_groups, new HeaderItemValue());
    }

    public void initFooterViewHolders() {
        addFooterViewHolder(FriendCountItemViewHolder.class, R.layout.contact_item_footer, new FooterItemValue());
    }

    protected void addHeaderViewHolder(Class<? extends HeaderItemViewHolder> clazz, int layoutResId, HeaderItemValue value) {
        listAdapter4Friends.addHeaderViewHolder(clazz, layoutResId, value);
    }

    protected void addFooterViewHolder(Class<? extends FooterItemViewHolder> clazz, int layoutResId, FooterItemValue value) {
        listAdapter4Friends.addFooterViewHolder(clazz, layoutResId, value);
    }

    //******************************************************************************** 礼品相关代码 START
    public void showGiftsToolsPopupWindow() {
        // 实例化SelectPicPopupWindow
        if(giftsToolsPopupWindow == null) {
            giftsToolsPopupWindow = new GiftsToolsPopupWindow(true, getActivity(), null);
            // 手动调用一下此方法，因giftsToolsPopupWindow只在使用时被初始化
            // ，所以很可能已错过了onResume的设置，所以此处要显式调用一下
            giftsToolsPopupWindow.forParentResume();
        }

        // 因好友列表界面在app退出前都不会被finish，如果放在new时才刷新一次就不能及时更新积分显示了（如果积分有更新的话）。
        // 所以每次show的时候都强制刷新一下积分数据以保证每次积分的即时刷新
        giftsToolsPopupWindow.loadGiftsData();

        // 显示窗口（设置layout在PopupWindow中显示的位置）
        giftsToolsPopupWindow.showAtLocation(getView(), Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0);
    }
    //******************************************************************************** 礼品相关代码 END

    /**
     * 快速索引字母被选中时。
     */
    @Override
    public void onLetterIndexSelected(String letter) {
        viewLetter4CurrentIndex.setVisibility(View.VISIBLE);
        viewLetter4CurrentIndex.setText(letter);

        List<FriendItemValue> data = listAdapter4Friends.getUsers();
        if(data == null || data.isEmpty()){
            return;
        }

        if ("↑".equalsIgnoreCase(letter)) {
            layoutManager.scrollToPositionWithOffset(0, 0);
        } else if ("☆".equalsIgnoreCase(letter)) {
            layoutManager.scrollToPositionWithOffset(listAdapter4Friends.headerCount(), 0);
        } else if ("#".equalsIgnoreCase(letter)) {
            for (int i = 0; i < data.size(); i++) {
                FriendItemValue friend = data.get(i);
                if (friend.getCategory().equals("#")) {
                    layoutManager.scrollToPositionWithOffset(listAdapter4Friends.headerCount() + i, 0);
                    break;
                }
            }
        } else {
            for (int i = 0; i < data.size(); i++) {
                FriendItemValue friend = data.get(i);
                if (friend.getCategory().compareTo(letter) >= 0) {
                    layoutManager.scrollToPositionWithOffset(i + listAdapter4Friends.headerCount(), 0);
                    break;
                }
            }
        }
    }

    /**
     * 快速索引字母被取消选中时。
     */
    @Override
    public void onLetterIndexUnselected() {
        viewLetter4CurrentIndex.setVisibility(View.GONE);
    }

    /**
     * 是否显示快速导航条。
     *
     * @param show true表示显示，否则不显示
     */
    public FriendListFragment showLetterIndexBar(boolean show) {
        this.showLetterIndexBar = show;
        if (viewLetterIndexBar != null) {
            viewLetterIndexBar.setVisibility(show ? View.VISIBLE : View.GONE);
            viewLetterIndexBar.setOnLetterIndexSelectionListener(this);
            viewLetterIndexBar.invalidate();
        }
        return this;
    }

    /**
     * 强制清除快速索引字母的选中状态ui显示（目前本方法主要用于主页中ViewPager中切换时）。
     */
    public void clearLetterIndexSelected(){
        viewLetter4CurrentIndex.setVisibility(View.GONE);
        viewLetterIndexBar.resetTouchIndex();;
    }

    @Override
    public void onFriendItemClick(FriendItemValue userInfo) {
//    // 进入与该好友的聊天界面
//    startActivity(IntentFactory.createChatIntent(getContext(), userInfo.getUserInfo().getUser_uid()));

        // 进入好友资料界面
      QueryFriendInfo.gotoWatchUserInfo(getActivity(), userInfo.getFriendInfo().getUser_uid(), null);
//    QueryFriendInfo.gotoWatchUserInfo(getActivity(), userInfo.getUserInfo().getUser_uid(), userInfo.getUserInfo());
    }

    @Override
    public void onHeaderItemClick(int index) {
        Log.i(TAG, "点击了头item，index="+index+"!!!!!!!");

        // 注意：此处返回的索引值是严格对应于ui上的item索引位置的哦

        if(index == 0){
            // 进入好友请求信息列表管理界面
            startActivity(IntentFactory.createVerificationRemindersActivityIntent(getActivity()));
        } else if(index == 1){
            // 查找好友
            startActivity(IntentFactory.createFindFriendIntent(getActivity()));
        } else if(index == 2){
            // 群聊列表
            startActivity(IntentFactory.createGroupsIntent(getContext(), false));
        }
    }

    @Override
    public void onFooterItemClick(int index) {
        // 默认什么也不做
    }
}
